﻿using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Adp.Core.Attribute;
using Adp;
using Adp.Common;
using Adp.Core.Services;
using System.Security.Cryptography;
using System.Net;
using Yqd.Enm;
using Yqd.Controllers;
using Yqd.Models;
using System.IO;
using System.Drawing;

namespace Yqd.Core
{
    public class DdService
    {
        YqdContext ctx;
        public DdService(YqdContext ctx)
        {
            this.ctx = ctx;
        }
        public string Get(UrlBuilder url, AccessTokenMode mode)
        {
            var wx = Yqd.Config.AppSecret(mode);

            var header = new WebHeaderCollection();
            string timestamp = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:sszzz");
            string nonceStr = GetTimeStamp() + new Random().Next(1000, 9999).ToString();
            var mac = "30";

            string rawstring = $"GET\n{timestamp}\n{nonceStr}\n{url.GetPath()}";
            var ps = url.GetParamString();
            if (ps.HasValue())
            {
                rawstring += "\n" + ps;
            }
            var sign = encrypt(rawstring, wx.AppSecret);
            header.Add("X-Hmac-Auth-Timestamp", timestamp);
            header.Add("X-Hmac-Auth-Version", "1.0");
            header.Add("X-Hmac-Auth-Nonce", nonceStr);
            header.Add("apiKey", wx.AppKey);
            header.Add("X-Hmac-Auth-Signature", sign);
            header.Add("X-Hmac-Auth-IP", Fn.GetIP());
            header.Add("X-Hmac-Auth-MAC", mac);
            var c = new CookieContainer();
            return Adp.Common.Fn.Get(Config.Api(url.ToString()), System.Text.Encoding.UTF8, header, ref c);
        }

        private string encrypt(string message, string secret)
        {
            secret = secret ?? "";
            UTF8Encoding encoding = new UTF8Encoding();
            byte[] bytes = encoding.GetBytes(secret);
            byte[] buffer = encoding.GetBytes(message);
            using (HMACSHA256 hmacsha = new HMACSHA256(bytes))
            {
                return Convert.ToBase64String(hmacsha.ComputeHash(buffer));
            }
        }
        private long GetTimeStamp()
        {
            TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            return Convert.ToInt64(ts.TotalSeconds);
        }

        public const string AccessTokenCachePath = "/Areas/Yqd/Configs/AccessToken.json";
        public string GetAccessToken(AccessTokenMode mode)
        {
            var wx = Config.AppSecret(mode);
            var CacheService = Fn.GetService<CacheService>();
            var token = CacheService.GetObject(AccessTokenCachePath)?["钉钉AccessToken_" + wx.AppKey];
            if (token == null || ((DateTime)token["expires_in"]) < DateTime.Now)
            {
                var url = UrlBuilder.Init("/gettoken.json");
                var i = Get(url, mode);
                var r = i.ToJObject();
                if (r["success"].ToObject<bool>())
                {
                    var ts = r["content"]["data"]["accessToken"].ToString();
                    token = CacheService.GetObject(AccessTokenCachePath, new JObject());
                    token["钉钉AccessToken_" + wx.AppKey] = JObject.FromObject(new
                    {
                        access_token = ts,
                        expires_in = DateTime.Now.AddSeconds(r["content"]["data"]["expiresIn"].ToObject<int>())
                    });
                    CacheService.SaveToFile(AccessTokenCachePath, token.ToString());
                    return ts;
                }
                else
                {
                    Adp.Logs.Error<DdService>("access_token error: {0}", i);
                }
                return "";
            }
            return token["access_token"].ToString();
        }

        public YqdUser GetAppUser(string auth_code)
        {
            var api = UrlBuilder.Init("/rpc/oauth2/dingtalk_app_user.json");
            var taken = GetAccessToken(AccessTokenMode.浙政钉通讯录);
            api.AddParam("access_token", taken);
            api.AddParam("auth_code", auth_code);
            var r = Post(api, AccessTokenMode.浙政钉通讯录).ToJObject();
            if (r["success"].ToObject<bool>())
            {
                try
                {
                    var employeeCode = r["content"]["data"]["employeeCode"].ToString();
                    var su = ctx.Yqd_User.FirstOrDefault(it => it.EmployeeCode == employeeCode && it.Status == 用户状态.使用中);
                    if (su != null)
                    {
                        var unit = ctx.Yqd_Unit.FirstOrDefault(it => it.OrganizationCode == su.UnitCode);
                        string UnitCode = "", UnitName = "";
                        if (unit != null)
                        {
                            UnitCode = unit.UnitCode;
                            UnitName = unit.Name;
                        }
                        var user = new YqdUser
                        {
                            Role = new List<角色类型>(),
                            Permit = new List<权限清单>(),
                            Avatar = su.Avatar,
                            Name = su.Name,
                            AccountId = su.AccountId,
                            UnitCode = UnitCode,
                            UnitName = UnitName,
                            OrganizationCode = su.UnitCode,
                            EmployeeCode = su.EmployeeCode
                        };
                        if (!string.IsNullOrWhiteSpace(su.Roles))
                        {
                            user.Role = su.Roles.Split(",").Select(it => (角色类型)int.Parse(it)).ToList();
                        }
                        if (!string.IsNullOrWhiteSpace(su.PermitItem))
                        {
                            user.Permit = su.PermitItem.Split(",").Select(it => (权限清单)int.Parse(it)).ToList();
                        }
                        return user;
                    }
                }
                catch
                {
                    return null;
                }
            }
            return null;
        }
        /// <summary>
        /// 获取员工基本信息
        /// </summary>
        /// <param name="employeeCode"></param>
        /// <param name="tenantId"></param>
        /// <returns></returns>
        public JObject GetEmployeeInfo(string employeeCode, int tenantId)
        {
            var api = UrlBuilder.Init("/mozi/employee/getEmployeeByCode");
            var taken = GetAccessToken(AccessTokenMode.浙政钉通讯录);
            api.AddParam("access_token", taken);
            api.AddParam("employeeCode", employeeCode);
            api.AddParam("tenantId", tenantId);
            var r = Post(api, AccessTokenMode.浙政钉通讯录).ToJObject();
            if (r["success"].ToObject<bool>())
            {
                return (JObject)r["content"]["data"];
            }
            return null;
        }
        /// <summary>
        /// 获取组织信息
        /// </summary>
        /// <param name="organizationCode"></param>
        /// <param name="tenantId"></param>
        public JObject GetOrganizationInfo(string organizationCode, int tenantId)
        {
            var api = UrlBuilder.Init("/mozi/organization/getOrganizationByCode");
            var taken = GetAccessToken(AccessTokenMode.浙政钉通讯录);
            api.AddParam("access_token", taken);
            api.AddParam("organizationCode", organizationCode);
            api.AddParam("tenantId", tenantId);
            var r = Post(api, AccessTokenMode.浙政钉通讯录).ToJObject();
            if (r["success"].ToObject<bool>())
            {
                return (JObject)r["content"]["data"];
            }
            return null;
        }
        /// <summary>
        /// 单位员工列表  获取:组织下面的单位员工/职级/人员编制
        /// </summary>
        /// <param name="organizationCode"></param>
        /// <param name="tenantId"></param>
        public List<string> pageOrganizationEmployeeCodes(string organizationCode, int tenantId)
        {
            var arr = new List<string>();
            var i = 1;
            while (true)
            {
                var api = UrlBuilder.Init("/mozi/organization/pageOrganizationEmployeeCodes");
                var taken = GetAccessToken(AccessTokenMode.浙政钉通讯录);
                api.AddParam("access_token", taken);
                api.AddParam("organizationCode", organizationCode);
                api.AddParam("pageNo", i++);
                api.AddParam("status", "A");
                api.AddParam("tenantId", tenantId);
                var r = Post(api, AccessTokenMode.浙政钉通讯录).ToJObject();
                if (r["success"].ToObject<bool>())
                {
                    var d = r["content"]["data"];
                    if (d != null)
                    {
                        var l = d.Select(it => it.ToString()).ToList();
                        arr.AddRange(l);
                        if (l.Count < 20)
                        {
                            break;
                        }
                    }
                    else
                    {
                        break;
                    }
                }
                else
                {
                    throw new Exception(r.ToString());
                }
            }
            return arr;
        }

        /// <summary>
        /// 单位员工列表  获取:组织下面的单位员工/职级/人员编制
        /// </summary>
        /// <param name="organizationCode"></param>
        /// <param name="tenantId"></param>
        public JArray pageOrganizationEmployeePositions(string organizationCode, int tenantId)
        {
            var api = UrlBuilder.Init("/mozi/organization/pageOrganizationEmployeePositions");
            var taken = GetAccessToken(AccessTokenMode.浙政钉通讯录);
            api.AddParam("access_token", taken);
            api.AddParam("organizationCode", organizationCode);
            api.AddParam("tenantId", tenantId);
            var r = Post(api, AccessTokenMode.浙政钉通讯录).ToJObject();
            if (r["success"].ToObject<bool>())
            {
                return (JArray)r["content"]["data"];
            }
            return null;
        }

        /// <summary>
        /// 获取通讯录权限范围 获取:组织的 organizationCode
        /// </summary>
        /// <param name="tenantId"></param>
        public JObject scopesV2(int tenantId)
        {
            var api = UrlBuilder.Init("/auth/scopesV2");
            var taken = GetAccessToken(AccessTokenMode.浙政钉通讯录);
            api.AddParam("access_token", taken);
            api.AddParam("tenantId", tenantId);
            var r = Post(api, AccessTokenMode.浙政钉通讯录).ToJObject();
            if (r["success"].ToObject<bool>())
            {
                return (JObject)r["content"];
            }
            return null;
        }
        /// <summary>
        /// 根据员工Code获取员工的任职  获取:职务层次code表/人员角色
        /// </summary>
        /// <param name="tenantId"></param>
        public JObject listEmployeePositionsByEmployeeCode(string employeeCode, int tenantId)
        {
            var api = UrlBuilder.Init("/mozi/employee/listEmployeePositionsByEmployeeCode");
            var taken = GetAccessToken(AccessTokenMode.浙政钉通讯录);
            api.AddParam("access_token", taken);
            api.AddParam("employeeCode", employeeCode);
            api.AddParam("tenantId", tenantId);
            var r = Post(api, AccessTokenMode.浙政钉通讯录).ToJObject();
            if (r["success"].ToObject<bool>())
            {
                return (JObject)r["content"]["data"];
            }
            return null;
        }
        /// <summary>
        /// 枚举字典查询
        /// </summary>
        /// <param name="tenantId"></param>
        public JArray queryByPropertyCode(string propertyCode, int tenantId)
        {
            var api = UrlBuilder.Init("/mozi/enumdictionary/queryByPropertyCode");
            var taken = GetAccessToken(AccessTokenMode.浙政钉通讯录);
            api.AddParam("access_token", taken);
            api.AddParam("propertyCode", propertyCode);
            api.AddParam("tenantId", tenantId);
            var r = Post(api, AccessTokenMode.浙政钉通讯录).ToJObject();
            if (r["success"].ToObject<bool>())
            {
                return (JArray)r["content"]["data"];
            }
            return null;
        }
        /// <summary>
        /// 分页获取下⼀级组织 Code 列表
        /// </summary>
        /// <param name="tenantId"></param>
        public List<string> pageSubOrganizationCodes(string organizationCode, int tenantId, bool checksub = false)
        {
            var arr = new List<string>();
            var i = 1;
            while (true)
            {
                var api = UrlBuilder.Init("/mozi/organization/pageSubOrganizationCodes");
                var taken = GetAccessToken(AccessTokenMode.浙政钉通讯录);
                api.AddParam("access_token", taken);
                api.AddParam("organizationCode", organizationCode);
                api.AddParam("pageNo", i++);
                api.AddParam("status", "A");
                api.AddParam("tenantId", tenantId);
                var r = Post(api, AccessTokenMode.浙政钉通讯录).ToJObject();
                if (r["success"].ToObject<bool>())
                {
                    var d = r["content"]["data"];
                    if (d != null)
                    {
                        var l = d.Select(it => it.ToString()).ToList();
                        arr = arr.Concat(l).ToList();
                        if (l.Count < 20)
                        {
                            break;
                        }
                    }
                    if (d == null)
                    {
                        break;
                    }
                }
                else
                {
                    throw new Exception(r.ToString());
                }
                if (checksub)
                {
                    break;
                }
            }
            return arr;
        }

        /// <summary>
        /// 分页获取下⼀级组织 Code 批量根据员工Code获取员⼯账号ID
        /// </summary>
        /// <param name="tenantId"></param>
        public JObject listEmployeeAccountIds(string employeeCodes, int tenantId)
        {
            var api = UrlBuilder.Init("/mozi/employee/listEmployeeAccountIds");
            var taken = GetAccessToken(AccessTokenMode.浙政钉通讯录);
            api.AddParam("access_token", taken);
            api.AddParam("employeeCodes", employeeCodes);
            api.AddParam("tenantId", tenantId);
            var r = Post(api, AccessTokenMode.浙政钉通讯录).ToJObject();
            if (r["success"].ToObject<bool>() && r["content"]["data"].Count() > 0)
            {
                return (JObject)r["content"]["data"][0];
            }
            return null;
        }



        /// <summary>
        /// 获取用户头像
        /// </summary>
        /// <param name="mediaId"></param>
        public bool GenerateAvatar(string mediaId, string filename)
        {
            var taken = GetAccessToken(AccessTokenMode.浙政钉通讯录);
            var url = UrlBuilder.Init(Config.Api("/media/download"), false);
            url.AddParam("access_token", taken);
            url.AddParam("media_id", mediaId);
            var wx = Config.AppSecret(AccessTokenMode.浙政钉通讯录);
            var header = new WebHeaderCollection();
            string timestamp = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:sszzz");
            string nonceStr = GetTimeStamp() + new Random().Next(1000, 9999).ToString();
            var mac = "30";
            string rawstring = $"GET\n{timestamp}\n{nonceStr}\n{url.GetPath()}";
            var ps = url.GetParamString();
            if (ps.HasValue())
            {
                rawstring += "\n" + ps;
            }
            HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url.ToString());
            req.Method = "GET";
            var sign = encrypt(rawstring, wx.AppSecret);
            req.Headers.Add("X-Hmac-Auth-Timestamp", timestamp);
            req.Headers.Add("X-Hmac-Auth-Version", "1.0");
            req.Headers.Add("X-Hmac-Auth-Nonce", nonceStr);
            req.Headers.Add("apiKey", wx.AppKey);
            req.Headers.Add("X-Hmac-Auth-Signature", sign);
            req.Headers.Add("X-Hmac-Auth-IP", Fn.GetIP());
            req.Headers.Add("X-Hmac-Auth-MAC", mac);
            req.CookieContainer = new CookieContainer();
            try
            {
                using (HttpWebResponse response = (HttpWebResponse)req.GetResponse())
                {
                    var stream = response.GetResponseStream();
                    FileStream fileStream = new FileStream(filename, FileMode.Create, FileAccess.Write);
                    byte[] bytes = new byte[1024];
                    var size = stream.Read(bytes, 0, bytes.Length);
                    while (size > 0)
                    {
                        fileStream.Write(bytes, 0, size);
                        size = stream.Read(bytes, 0, bytes.Length);
                    }
                    response.Close();
                    stream.Close();
                    fileStream.Close();
                    return true;
                }
            }
            catch (Exception ex)
            {
                Fn.Log(ex.Message);
                return false;
            }
        }

        /// <summary>
        /// 获取应用可见性
        /// </summary>
        /// <param name="tenantId"></param>
        public void getAppUsedRange(string currentPage, int tenantId)
        {
            var api = UrlBuilder.Init("/openplatform/appcenter/getAppUsedRange");
            var taken = GetAccessToken(AccessTokenMode.浙政钉通讯录);
            api.AddParam("access_token", taken);
            api.AddParam("currentPage", currentPage);
            api.AddParam("tenantId", tenantId);
            //api.AddParam("status", "A");
            var r = Post(api, AccessTokenMode.浙政钉通讯录).ToJObject();
            if (r["success"].ToObject<bool>())
            {
                var data = r["content"]["data"];
                //return (
                //    data["employeeCode"].ToString(),
                //    data["employeeName"].ToString(),
                //    data["status"].ToString(),              //状态
                //    data["empGender"].ToString(),           //姓别
                //    data["govEmpAvatar"].ToString(),        //头像
                //    data["empJobLevelCode"].ToString()      //职务等级
                //);
            }
            //return ("", "", "", "", "", "");
            return;
        }
        /// <summary>
        /// 添加应用可见性
        /// </summary>
        /// <param name="tenantId"></param>
        public void addAppUsedRange(string orgCodes, string accountIds, int tenantId)
        {
            var api = UrlBuilder.Init("/openplatform/appcenter/addAppUsedRange");
            var taken = GetAccessToken(AccessTokenMode.浙政钉通讯录);
            api.AddParam("access_token", taken);
            api.AddParam("orgCodes", orgCodes);
            api.AddParam("accountIds", accountIds);
            api.AddParam("tenantId", tenantId);
            //api.AddParam("status", "A");
            var r = Post(api, AccessTokenMode.浙政钉通讯录).ToJObject();
            if (r["success"].ToObject<bool>())
            {
                var data = r["content"]["data"];
                //return (
                //    data["employeeCode"].ToString(),
                //    data["employeeName"].ToString(),
                //    data["status"].ToString(),              //状态
                //    data["empGender"].ToString(),           //姓别
                //    data["govEmpAvatar"].ToString(),        //头像
                //    data["empJobLevelCode"].ToString()      //职务等级
                //);
            }
            //return ("", "", "", "", "", "");
            return;
        }
        /// <summary>
        /// 删除应用可见性
        /// </summary>
        /// <param name="tenantId"></param>
        public void deleteAppUsedRange(string orgCodes, string accountIds, int tenantId)
        {
            var api = UrlBuilder.Init("/openplatform/appcenter/deleteAppUsedRange");
            var taken = GetAccessToken(AccessTokenMode.浙政钉通讯录);
            api.AddParam("access_token", taken);
            api.AddParam("orgCodes", orgCodes);
            api.AddParam("accountIds", accountIds);
            api.AddParam("tenantId", tenantId);
            //api.AddParam("status", "A");
            var r = Post(api, AccessTokenMode.浙政钉通讯录).ToJObject();
            if (r["success"].ToObject<bool>())
            {
                var data = r["content"]["data"];
                //return (
                //    data["employeeCode"].ToString(),
                //    data["employeeName"].ToString(),
                //    data["status"].ToString(),              //状态
                //    data["empGender"].ToString(),           //姓别
                //    data["govEmpAvatar"].ToString(),        //头像
                //    data["empJobLevelCode"].ToString()      //职务等级
                //);
            }
            //return ("", "", "", "", "", "");
            return;
        }

        public string GetPropertyNameByCode(string type, string value)
        {
            return Env.Config.Init("Yqd", "枚举字典", type, value).First()?.Value ?? "";
        }

        /// <summary>
        /// DING API开放接口
        /// </summary>
        /// <param name="senderAccountId">发送者帐号ID</param>
        /// <param name="receiverAccountIds">接收者帐号ID，以“,”隔开</param>
        /// <param name="body">发送文本</param>
        public string DingSend(string senderAccountId, string receiverAccountIds, string body)
        {
            var api = UrlBuilder.Init("/gov/ding/isv/send.json", false);
            var taken = GetAccessToken(AccessTokenMode.浙政钉通讯录);
            api.AddParam("body", JObject.FromObject(new
            {
                text = body
            }).ToString());
            api.AddParam("bodyType", "text");
            api.AddParam("creator", JObject.FromObject(new
            {
                accountId = senderAccountId
            }).ToString());
            api.AddParam("notifyType", "app");
            api.AddParam("receivers", JArray.FromObject(receiverAccountIds.Split(",").Select(it => new
            {
                accountId = it
            })).ToString());
            var config = Config.AppSecret(AccessTokenMode.浙政钉通讯录);
            api.AddParam("tenantId", config.TenantId);
            api.AddParam("textType", "plaintext");
            return Post(api, AccessTokenMode.浙政钉通讯录);
        }


        public string workNotification(string organizationCodes, string receiverIds, string bizMsgId, string msg, string IP)
        {
            try {
                var api = UrlBuilder.Init("/message/workNotification", false);
                var taken = GetAccessToken(AccessTokenMode.浙政钉通讯录);

                if (string.IsNullOrWhiteSpace(organizationCodes) && string.IsNullOrWhiteSpace(receiverIds))
                {
                    return "接收对象不能为空";
                }

                if (!string.IsNullOrWhiteSpace(bizMsgId))
                {
                    api.AddParam("bizMsgId", bizMsgId);
                }

                api.AddParam("msg", msg);

                if (!string.IsNullOrWhiteSpace(organizationCodes))
                {
                    api.AddParam("organizationCodes", organizationCodes);
                }

                if (!string.IsNullOrWhiteSpace(receiverIds))
                {
                    api.AddParam("receiverIds", receiverIds);
                }
                var config = Config.AppSecret(AccessTokenMode.浙政钉通讯录);
                api.AddParam("tenantId", config.TenantId);

                //Logs.Warning<DdService>("开始 post,ip{0}",IP);
                return Post(api, AccessTokenMode.浙政钉通讯录, IP);
            }
            catch (Exception e) {
                Logs.Warning<DdService>("workNotification 莫名其妙发送报错{0},Source:{1},InnerException{2},TargetSite:{3},StackTrace:{4}", e.Message, e.Source, e.InnerException, e.TargetSite, e.StackTrace);
                return string.Format("workNotification 莫名其妙发送报错{0},Source:{1},InnerException{2},TargetSite:{3},StackTrace:{4}", e.Message, e.Source, e.InnerException, e.TargetSite, e.StackTrace);

            }

        }

        public string Notification(string UnitCode, string headTitle, string TaskName, string text, bool IsDd = false)
        {
            var user = ctx.Yqd_User.Where(it => it.AccountId > 0 );
            if (IsDd)
            {
                user = user.Where(it => ("," + it.Roles + ",").Contains("," + (int)角色类型.督查人员 + ","));
            }
            else
            {
                if (!string.IsNullOrWhiteSpace(UnitCode))
                {
                    var unit = ctx.Yqd_Unit.FirstOrDefault(it => it.UnitCode == UnitCode);
                    if (unit != null && !string.IsNullOrWhiteSpace(unit.OrganizationCode))
                    {
                        user = user.Where(it => it.UnitCode == unit.OrganizationCode && ("," + it.Roles + ",").Contains("," + (int)角色类型.部门联络员 + ","));
                    }
                }
                else
                    user = user.Where(it => ("," + it.Roles + ",").Contains("," + (int)角色类型.市领导 + ",") || ("," + it.Roles + ",").Contains("," + (int)角色类型.领导秘书 + ","));
            }
            var receiverIds = string.Join(",", user.Select(it => it.AccountId));
            var msg = JObject.FromObject(new
            {
                msgtype = "oa",
                oa = JObject.FromObject(new
                {
                    message_url = "https://yqd.hd.yw.gov.cn/auth",
                    pc_message_url = "https://yqd.hd.yw.gov.cn/auth",
                    head = JObject.FromObject(new
                    {
                        bgcolor = "000000",
                        text = headTitle

                    }),
                    body = JObject.FromObject(new
                    {
                        title = TaskName,
                        content = text + "任务详情见义起督-政府效能管理应用。登录路径：浙政钉（电脑端）-工作台-义乌市-数字政府-义起督"
                    })
                })
            }).ToString();
            var random = new byte[2];
            var rng = new RNGCryptoServiceProvider();
            rng.GetNonZeroBytes(random);
            var sb = new StringBuilder(4);
            for (var i = 0; i < random.Length; i++)
            {
                sb.Append(string.Format("{0:X2}", random[i]));
            }
            Fn.Log("receiverIds：" + string.Join("," , user.Select(it => it.Name)));
            return workNotification("", receiverIds, sb.ToString(), msg, Fn.GetIP());
        }

        public string GetNotification_OA(Yqd_Rank rank)
        {

            var arr = new ArrayList();
            arr.Add(new
            {
                key = "效能指数",
                value = rank.Score
            });
            if (rank.UnitCode != "330782000000")
            {
                arr.Add(new
                {
                    key = "全市排名",
                    value = rank.UnitCode == "330782000000" ? "--" : rank.Tactic.ToString()
                });

            }
          
            //var dt=DateTime
            var msg = JObject.FromObject(new
            {
                msgtype = "oa",
                oa = JObject.FromObject(new
                {
                    message_url = "https://yqd.hd.yw.gov.cn/gzd#/workNotification/UnitRank?bizmsgid="+rank.RankID,
                    pc_message_url = "https://yqd.hd.yw.gov.cn/gzd#/workNotification/UnitRank?bizmsgid=" + rank.RankID,
                    head = JObject.FromObject(new
                    {
                        bgcolor = "000000",
                        text = "部门效能评价报告"

                    }),
                    body = JObject.FromObject(new
                    {
                        title = rank.Name+ "("+rank.ResultTime.ToString("yyyy-MM-dd")+")",
                        form = JArray.FromObject(arr),
                        content = "滞后事项"+ rank.ZH + "项，预警事项" + rank.YJ + "项，正常事项" + rank.ZC + "项，已完成事项" + rank.WC + "项。"
                    })

                })
            }).ToString();

            return msg;
        }
        public string GetNotification_Text(string Msg)
        {

            var msg = JObject.FromObject(new
            {
                msgtype = "text",
                text = JObject.FromObject(new
                {
                    content = Msg
                })
            }).ToString();

            return msg;
        }

        public string Post(UrlBuilder url, AccessTokenMode mode)
        {
           return Post(url, mode, "");

        }

        public string Post(UrlBuilder url, AccessTokenMode mode,string  IP)
        {

            try
            {
                var header = new WebHeaderCollection();
                string timestamp = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:sszzz");
                string nonceStr = GetTimeStamp() + new Random().Next(1000, 9999).ToString();
                var mac = "30";

                string rawstring = $"POST\n{timestamp}\n{nonceStr}\n{url.GetPath()}";
                var p = "";

                foreach (var item in url.Params)
                {
                    p += $"&{item.Name}={(item.Value)}";
                }
                if (url.Params.Count > 0)
                {
                    rawstring += "\n" + p.Trim('&');
                }

                var wx = Config.AppSecret(mode);
                var sign = encrypt(rawstring, wx.AppSecret);
                header.Add("X-Hmac-Auth-Timestamp", timestamp);
                header.Add("X-Hmac-Auth-Version", "1.0");
                header.Add("X-Hmac-Auth-Nonce", nonceStr);
                header.Add("apiKey", wx.AppKey);
                header.Add("X-Hmac-Auth-Signature", sign);
                header.Add("X-Hmac-Auth-IP", string.IsNullOrWhiteSpace(IP)? Fn.GetIP(): IP);
                header.Add("X-Hmac-Auth-MAC", mac);
                var c = new CookieContainer();
                p = "";
                foreach (var item in url.Params)
                {
                    p += $"&{item.Name}={System.Web.HttpUtility.UrlEncode(item.Value)}";
                }
                return Fn.Post(Config.Api(url.GetUrl()), p.Trim('&'), Encoding.UTF8, header, ref c);
            }
            catch (Exception e)
            {
                Logs.Warning<DdService>("Post莫名其妙报错了{0},Source:{1},InnerException{2},TargetSite:{3},StackTrace:{4}", e.Message, e.Source, e.InnerException, e.TargetSite, e.StackTrace);
                return string.Format(" Post莫名其妙报错了{0},Source:{1},InnerException{2},TargetSite:{3},StackTrace:{4}", e.Message, e.Source, e.InnerException, e.TargetSite, e.StackTrace);
            }



        }
    }
}
